#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
访问者模式 (Visitor Pattern) - Python实现详解

概述引导：
访问者模式表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
这种类型的设计模式属于行为型模式。

学习要点：
1. 传统访问者模式实现
2. Python函数式访问者
3. 装饰器访问者
4. 动态分发访问者
5. 异步访问者

Java对比要点：
- Java使用接口和方法重载实现访问者
- Python使用动态分发和函数式编程
- Python的装饰器提供更灵活的实现
- Python支持运行时动态添加访问者

关键理解：
Python的动态特性使访问者模式实现更加灵活，可以避免传统实现的复杂性。
"""

from abc import ABC, abstractmethod
from typing import Any, Dict, List, Callable, Optional, Union, Type, TypeVar, Generic
from dataclasses import dataclass, field
from enum import Enum, auto
import time
import json
import inspect
import functools
import asyncio
from datetime import datetime
import weakref
from collections import defaultdict
import threading
from concurrent.futures import ThreadPoolExecutor
import logging
import re
from pathlib import Path


# ============= 传统访问者模式实现 =============

class Element(ABC):
    """
    元素抽象基类
    
    定义accept方法接受访问者
    """
    
    @abstractmethod
    def accept(self, visitor: 'Visitor'):
        """接受访问者"""
        pass


class Visitor(ABC):
    """
    访问者抽象基类
    
    定义访问不同元素的方法
    """
    
    @abstractmethod
    def visit_concrete_element_a(self, element: 'ConcreteElementA'):
        """访问具体元素A"""
        pass
    
    @abstractmethod
    def visit_concrete_element_b(self, element: 'ConcreteElementB'):
        """访问具体元素B"""
        pass


class ConcreteElementA(Element):
    """
    具体元素A
    
    实现accept方法，调用访问者的相应方法
    """
    
    def __init__(self, data: str):
        self.data = data
    
    def accept(self, visitor: Visitor):
        """接受访问者"""
        return visitor.visit_concrete_element_a(self)
    
    def operation_a(self) -> str:
        """元素A特有的操作"""
        return f"ElementA operation with data: {self.data}"


class ConcreteElementB(Element):
    """
    具体元素B
    
    实现accept方法，调用访问者的相应方法
    """
    
    def __init__(self, value: int):
        self.value = value
    
    def accept(self, visitor: Visitor):
        """接受访问者"""
        return visitor.visit_concrete_element_b(self)
    
    def operation_b(self) -> int:
        """元素B特有的操作"""
        return self.value * 2


class ConcreteVisitor1(Visitor):
    """
    具体访问者1 - 打印访问者
    
    实现对不同元素的访问操作
    """
    
    def __init__(self):
        self.results = []
    
    def visit_concrete_element_a(self, element: ConcreteElementA):
        """访问元素A"""
        result = f"Visitor1 访问 ElementA: {element.operation_a()}"
        self.results.append(result)
        print(f"  {result}")
        return result
    
    def visit_concrete_element_b(self, element: ConcreteElementB):
        """访问元素B"""
        result = f"Visitor1 访问 ElementB: {element.operation_b()}"
        self.results.append(result)
        print(f"  {result}")
        return result
    
    def get_results(self) -> List[str]:
        """获取访问结果"""
        return self.results.copy()


class ConcreteVisitor2(Visitor):
    """
    具体访问者2 - 统计访问者
    
    统计访问的元素信息
    """
    
    def __init__(self):
        self.element_count = defaultdict(int)
        self.total_value = 0
    
    def visit_concrete_element_a(self, element: ConcreteElementA):
        """访问元素A"""
        self.element_count['ElementA'] += 1
        self.total_value += len(element.data)
        result = f"统计 ElementA: 数据长度={len(element.data)}"
        print(f"  {result}")
        return result
    
    def visit_concrete_element_b(self, element: ConcreteElementB):
        """访问元素B"""
        self.element_count['ElementB'] += 1
        self.total_value += element.value
        result = f"统计 ElementB: 值={element.value}"
        print(f"  {result}")
        return result
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取统计信息"""
        return {
            'element_count': dict(self.element_count),
            'total_value': self.total_value,
            'total_elements': sum(self.element_count.values())
        }


class ObjectStructure:
    """
    对象结构
    
    管理元素集合，提供遍历接口
    """
    
    def __init__(self):
        self.elements: List[Element] = []
    
    def add_element(self, element: Element):
        """添加元素"""
        self.elements.append(element)
    
    def remove_element(self, element: Element):
        """移除元素"""
        if element in self.elements:
            self.elements.remove(element)
    
    def accept(self, visitor: Visitor):
        """接受访问者，遍历所有元素"""
        results = []
        for element in self.elements:
            result = element.accept(visitor)
            results.append(result)
        return results
    
    def get_element_count(self) -> int:
        """获取元素数量"""
        return len(self.elements)
    
    def get_elements_by_type(self, element_type: Type) -> List[Element]:
        """按类型获取元素"""
        return [elem for elem in self.elements if isinstance(elem, element_type)]


# ============= Python函数式访问者实现 =============

class FunctionalElement:
    """
    函数式元素基类
    
    使用函数式方法实现访问者模式
    """
    
    def __init__(self, element_type: str, data: Any):
        self.element_type = element_type
        self.data = data
        self.timestamp = datetime.now()
    
    def accept(self, visitor_func: Callable):
        """接受访问者函数"""
        return visitor_func(self)
    
    def __repr__(self):
        return f"{self.__class__.__name__}(type={self.element_type}, data={self.data})"


class DocumentElement(FunctionalElement):
    """
    文档元素
    
    表示文档类型的元素
    """
    
    def __init__(self, title: str, content: str, author: str):
        super().__init__("document", {
            'title': title,
            'content': content,
            'author': author
        })
        self.word_count = len(content.split())
    
    @property
    def title(self) -> str:
        return self.data['title']
    
    @property
    def content(self) -> str:
        return self.data['content']
    
    @property
    def author(self) -> str:
        return self.data['author']


class ImageElement(FunctionalElement):
    """
    图片元素
    
    表示图片类型的元素
    """
    
    def __init__(self, filename: str, width: int, height: int, format_type: str):
        super().__init__("image", {
            'filename': filename,
            'width': width,
            'height': height,
            'format': format_type
        })
        self.size = width * height
    
    @property
    def filename(self) -> str:
        return self.data['filename']
    
    @property
    def width(self) -> int:
        return self.data['width']
    
    @property
    def height(self) -> int:
        return self.data['height']
    
    @property
    def format_type(self) -> str:
        return self.data['format']


class VideoElement(FunctionalElement):
    """
    视频元素
    
    表示视频类型的元素
    """
    
    def __init__(self, filename: str, duration: float, resolution: str, codec: str):
        super().__init__("video", {
            'filename': filename,
            'duration': duration,
            'resolution': resolution,
            'codec': codec
        })
        self.bitrate = self._calculate_bitrate()
    
    def _calculate_bitrate(self) -> float:
        """计算比特率（模拟）"""
        base_rate = 1000  # kbps
        if '4K' in self.resolution:
            return base_rate * 8
        elif '1080p' in self.resolution:
            return base_rate * 4
        elif '720p' in self.resolution:
            return base_rate * 2
        else:
            return base_rate
    
    @property
    def filename(self) -> str:
        return self.data['filename']
    
    @property
    def duration(self) -> float:
        return self.data['duration']
    
    @property
    def resolution(self) -> str:
        return self.data['resolution']
    
    @property
    def codec(self) -> str:
        return self.data['codec']


# 函数式访问者实现
def print_visitor(element: FunctionalElement) -> str:
    """
    打印访问者函数
    
    打印元素信息
    """
    if isinstance(element, DocumentElement):
        result = f"文档: {element.title} (作者: {element.author}, 字数: {element.word_count})"
    elif isinstance(element, ImageElement):
        result = f"图片: {element.filename} ({element.width}x{element.height}, {element.format_type})"
    elif isinstance(element, VideoElement):
        result = f"视频: {element.filename} ({element.resolution}, {element.duration}s, {element.codec})"
    else:
        result = f"未知元素: {element}"
    
    print(f"  {result}")
    return result


def size_calculator_visitor(element: FunctionalElement) -> Dict[str, Any]:
    """
    大小计算访问者函数
    
    计算元素的大小信息
    """
    if isinstance(element, DocumentElement):
        # 估算文档大小（字符数 * 2字节）
        size = len(element.content) * 2
        return {
            'type': 'document',
            'size_bytes': size,
            'size_kb': size / 1024,
            'word_count': element.word_count
        }
    elif isinstance(element, ImageElement):
        # 估算图片大小（像素数 * 3字节）
        size = element.size * 3
        return {
            'type': 'image',
            'size_bytes': size,
            'size_mb': size / (1024 * 1024),
            'pixels': element.size
        }
    elif isinstance(element, VideoElement):
        # 估算视频大小（比特率 * 时长）
        size = element.bitrate * element.duration * 1000 / 8  # 转换为字节
        return {
            'type': 'video',
            'size_bytes': size,
            'size_mb': size / (1024 * 1024),
            'duration': element.duration,
            'bitrate': element.bitrate
        }
    else:
        return {'type': 'unknown', 'size_bytes': 0}


def metadata_extractor_visitor(element: FunctionalElement) -> Dict[str, Any]:
    """
    元数据提取访问者函数
    
    提取元素的元数据信息
    """
    base_metadata = {
        'element_type': element.element_type,
        'timestamp': element.timestamp.isoformat(),
        'class_name': element.__class__.__name__
    }
    
    if isinstance(element, DocumentElement):
        base_metadata.update({
            'title': element.title,
            'author': element.author,
            'word_count': element.word_count,
            'content_preview': element.content[:100] + '...' if len(element.content) > 100 else element.content
        })
    elif isinstance(element, ImageElement):
        base_metadata.update({
            'filename': element.filename,
            'dimensions': f"{element.width}x{element.height}",
            'format': element.format_type,
            'total_pixels': element.size
        })
    elif isinstance(element, VideoElement):
        base_metadata.update({
            'filename': element.filename,
            'duration': element.duration,
            'resolution': element.resolution,
            'codec': element.codec,
            'estimated_bitrate': element.bitrate
        })
    
    return base_metadata


# ============= 装饰器访问者实现 =============

class VisitorRegistry:
    """
    访问者注册表
    
    管理不同类型元素的访问者函数
    """
    
    def __init__(self):
        self.visitors: Dict[str, Dict[Type, Callable]] = defaultdict(dict)
    
    def register(self, visitor_name: str, element_type: Type):
        """注册访问者装饰器"""
        def decorator(func: Callable):
            self.visitors[visitor_name][element_type] = func
            return func
        return decorator
    
    def visit(self, visitor_name: str, element: Any) -> Any:
        """执行访问"""
        element_type = type(element)
        
        # 查找精确匹配的访问者
        if element_type in self.visitors[visitor_name]:
            return self.visitors[visitor_name][element_type](element)
        
        # 查找父类匹配的访问者
        for registered_type, visitor_func in self.visitors[visitor_name].items():
            if isinstance(element, registered_type):
                return visitor_func(element)
        
        # 没有找到合适的访问者
        raise ValueError(f"No visitor found for {visitor_name} and {element_type}")
    
    def get_registered_visitors(self) -> Dict[str, List[Type]]:
        """获取已注册的访问者"""
        return {
            name: list(type_dict.keys())
            for name, type_dict in self.visitors.items()
        }


# 创建全局访问者注册表
visitor_registry = VisitorRegistry()


# 使用装饰器注册访问者
@visitor_registry.register('formatter', DocumentElement)
def format_document(element: DocumentElement) -> str:
    """格式化文档元素"""
    return f"📄 {element.title}\n   作者: {element.author}\n   字数: {element.word_count}"


@visitor_registry.register('formatter', ImageElement)
def format_image(element: ImageElement) -> str:
    """格式化图片元素"""
    return f"🖼️  {element.filename}\n   尺寸: {element.width}x{element.height}\n   格式: {element.format_type}"


@visitor_registry.register('formatter', VideoElement)
def format_video(element: VideoElement) -> str:
    """格式化视频元素"""
    return f"🎥 {element.filename}\n   时长: {element.duration}s\n   分辨率: {element.resolution}"


@visitor_registry.register('validator', DocumentElement)
def validate_document(element: DocumentElement) -> Dict[str, Any]:
    """验证文档元素"""
    issues = []
    
    if not element.title.strip():
        issues.append("标题不能为空")
    
    if not element.author.strip():
        issues.append("作者不能为空")
    
    if element.word_count < 10:
        issues.append("内容过短")
    
    return {
        'valid': len(issues) == 0,
        'issues': issues,
        'element_type': 'document'
    }


@visitor_registry.register('validator', ImageElement)
def validate_image(element: ImageElement) -> Dict[str, Any]:
    """验证图片元素"""
    issues = []
    
    if element.width <= 0 or element.height <= 0:
        issues.append("图片尺寸必须大于0")
    
    if element.format_type.lower() not in ['jpg', 'jpeg', 'png', 'gif', 'bmp']:
        issues.append("不支持的图片格式")
    
    if element.size > 10000000:  # 10M像素
        issues.append("图片尺寸过大")
    
    return {
        'valid': len(issues) == 0,
        'issues': issues,
        'element_type': 'image'
    }


@visitor_registry.register('validator', VideoElement)
def validate_video(element: VideoElement) -> Dict[str, Any]:
    """验证视频元素"""
    issues = []
    
    if element.duration <= 0:
        issues.append("视频时长必须大于0")
    
    if element.codec.lower() not in ['h264', 'h265', 'vp9', 'av1']:
        issues.append("不支持的视频编码")
    
    if element.duration > 7200:  # 2小时
        issues.append("视频时长过长")
    
    return {
        'valid': len(issues) == 0,
        'issues': issues,
        'element_type': 'video'
    }


@visitor_registry.register('analyzer', DocumentElement)
def analyze_document(element: DocumentElement) -> Dict[str, Any]:
    """分析文档元素"""
    content = element.content.lower()
    
    # 简单的关键词分析
    keywords = ['python', 'java', 'programming', 'code', 'development']
    found_keywords = [kw for kw in keywords if kw in content]
    
    # 句子数量估算
    sentence_count = content.count('.') + content.count('!') + content.count('?')
    
    return {
        'word_count': element.word_count,
        'sentence_count': sentence_count,
        'avg_words_per_sentence': element.word_count / max(sentence_count, 1),
        'found_keywords': found_keywords,
        'keyword_density': len(found_keywords) / element.word_count if element.word_count > 0 else 0,
        'reading_time_minutes': element.word_count / 200  # 假设每分钟200词
    }


@visitor_registry.register('analyzer', ImageElement)
def analyze_image(element: ImageElement) -> Dict[str, Any]:
    """分析图片元素"""
    aspect_ratio = element.width / element.height
    
    # 判断图片类型
    if abs(aspect_ratio - 1.0) < 0.1:
        image_type = "正方形"
    elif aspect_ratio > 1.5:
        image_type = "横向"
    elif aspect_ratio < 0.67:
        image_type = "纵向"
    else:
        image_type = "标准"
    
    # 判断分辨率等级
    if element.size >= 8000000:  # 8M像素
        resolution_level = "超高清"
    elif element.size >= 2000000:  # 2M像素
        resolution_level = "高清"
    elif element.size >= 500000:  # 0.5M像素
        resolution_level = "标清"
    else:
        resolution_level = "低清"
    
    return {
        'aspect_ratio': round(aspect_ratio, 2),
        'image_type': image_type,
        'resolution_level': resolution_level,
        'total_pixels': element.size,
        'estimated_file_size_mb': (element.size * 3) / (1024 * 1024),  # 估算文件大小
        'is_high_resolution': element.size >= 2000000
    }


@visitor_registry.register('analyzer', VideoElement)
def analyze_video(element: VideoElement) -> Dict[str, Any]:
    """分析视频元素"""
    # 判断视频长度类型
    if element.duration < 60:
        duration_type = "短视频"
    elif element.duration < 600:
        duration_type = "中等长度"
    elif element.duration < 3600:
        duration_type = "长视频"
    else:
        duration_type = "超长视频"
    
    # 判断质量等级
    if '4K' in element.resolution:
        quality_level = "超高清"
    elif '1080p' in element.resolution:
        quality_level = "高清"
    elif '720p' in element.resolution:
        quality_level = "标清"
    else:
        quality_level = "低清"
    
    # 估算文件大小
    estimated_size_mb = (element.bitrate * element.duration * 1000 / 8) / (1024 * 1024)
    
    return {
        'duration_type': duration_type,
        'quality_level': quality_level,
        'estimated_bitrate': element.bitrate,
        'estimated_size_mb': round(estimated_size_mb, 2),
        'duration_minutes': round(element.duration / 60, 2),
        'is_streaming_friendly': element.bitrate <= 5000 and 'h264' in element.codec.lower()
    }


# ============= 动态分发访问者实现 =============

class DynamicVisitor:
    """
    动态分发访问者
    
    使用Python的动态特性实现访问者模式
    """
    
    def __init__(self):
        self.visit_count = defaultdict(int)
        self.results = []
    
    def visit(self, element: Any) -> Any:
        """动态分发访问方法"""
        # 获取元素类型名称
        element_type = element.__class__.__name__
        
        # 构造方法名
        method_name = f"visit_{element_type.lower()}"
        
        # 检查是否有对应的访问方法
        if hasattr(self, method_name):
            method = getattr(self, method_name)
            result = method(element)
        else:
            # 使用默认访问方法
            result = self.visit_default(element)
        
        # 记录访问统计
        self.visit_count[element_type] += 1
        self.results.append(result)
        
        return result
    
    def visit_default(self, element: Any) -> str:
        """默认访问方法"""
        return f"访问未知元素: {element.__class__.__name__}"
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取访问统计"""
        return {
            'visit_count': dict(self.visit_count),
            'total_visits': sum(self.visit_count.values()),
            'unique_types': len(self.visit_count),
            'results_count': len(self.results)
        }


class ReportVisitor(DynamicVisitor):
    """
    报告生成访问者
    
    生成详细的元素报告
    """
    
    def __init__(self):
        super().__init__()
        self.report_data = []
    
    def visit_documentelement(self, element: DocumentElement) -> Dict[str, Any]:
        """访问文档元素"""
        report = {
            'type': 'document',
            'title': element.title,
            'author': element.author,
            'word_count': element.word_count,
            'timestamp': element.timestamp.isoformat(),
            'content_preview': element.content[:200] + '...' if len(element.content) > 200 else element.content
        }
        self.report_data.append(report)
        return report
    
    def visit_imageelement(self, element: ImageElement) -> Dict[str, Any]:
        """访问图片元素"""
        report = {
            'type': 'image',
            'filename': element.filename,
            'dimensions': f"{element.width}x{element.height}",
            'format': element.format_type,
            'size_pixels': element.size,
            'timestamp': element.timestamp.isoformat()
        }
        self.report_data.append(report)
        return report
    
    def visit_videoelement(self, element: VideoElement) -> Dict[str, Any]:
        """访问视频元素"""
        report = {
            'type': 'video',
            'filename': element.filename,
            'duration': element.duration,
            'resolution': element.resolution,
            'codec': element.codec,
            'bitrate': element.bitrate,
            'timestamp': element.timestamp.isoformat()
        }
        self.report_data.append(report)
        return report
    
    def generate_summary_report(self) -> Dict[str, Any]:
        """生成汇总报告"""
        total_documents = sum(1 for item in self.report_data if item['type'] == 'document')
        total_images = sum(1 for item in self.report_data if item['type'] == 'image')
        total_videos = sum(1 for item in self.report_data if item['type'] == 'video')
        
        # 计算总字数
        total_words = sum(item.get('word_count', 0) for item in self.report_data if item['type'] == 'document')
        
        # 计算总视频时长
        total_duration = sum(item.get('duration', 0) for item in self.report_data if item['type'] == 'video')
        
        return {
            'summary': {
                'total_elements': len(self.report_data),
                'documents': total_documents,
                'images': total_images,
                'videos': total_videos
            },
            'content_stats': {
                'total_words': total_words,
                'total_video_duration': total_duration,
                'avg_words_per_document': total_words / max(total_documents, 1)
            },
            'detailed_reports': self.report_data
        }


# ============= 异步访问者实现 =============

class AsyncVisitor:
    """
    异步访问者基类
    
    支持异步操作的访问者实现
    """
    
    def __init__(self):
        self.results = []
        self.processing_time = 0
    
    async def visit(self, element: Any) -> Any:
        """异步访问方法"""
        start_time = time.time()
        
        # 动态分发到具体的异步访问方法
        element_type = element.__class__.__name__
        method_name = f"visit_{element_type.lower()}"
        
        if hasattr(self, method_name):
            method = getattr(self, method_name)
            if asyncio.iscoroutinefunction(method):
                result = await method(element)
            else:
                result = method(element)
        else:
            result = await self.visit_default(element)
        
        self.processing_time += time.time() - start_time
        self.results.append(result)
        
        return result
    
    async def visit_default(self, element: Any) -> str:
        """默认异步访问方法"""
        await asyncio.sleep(0.01)  # 模拟异步操作
        return f"异步访问: {element.__class__.__name__}"
    
    async def visit_multiple(self, elements: List[Any]) -> List[Any]:
        """并发访问多个元素"""
        tasks = [self.visit(element) for element in elements]
        return await asyncio.gather(*tasks)
    
    def get_performance_stats(self) -> Dict[str, Any]:
        """获取性能统计"""
        return {
            'total_processing_time': self.processing_time,
            'elements_processed': len(self.results),
            'avg_processing_time': self.processing_time / max(len(self.results), 1)
        }


class AsyncProcessingVisitor(AsyncVisitor):
    """
    异步处理访问者
    
    模拟耗时的异步处理操作
    """
    
    async def visit_documentelement(self, element: DocumentElement) -> Dict[str, Any]:
        """异步处理文档元素"""
        # 模拟文档处理（如OCR、翻译等）
        await asyncio.sleep(0.1)
        
        # 模拟复杂的文本分析
        word_analysis = await self._analyze_text(element.content)
        
        return {
            'type': 'document',
            'title': element.title,
            'processing_status': 'completed',
            'word_analysis': word_analysis,
            'processed_at': datetime.now().isoformat()
        }
    
    async def visit_imageelement(self, element: ImageElement) -> Dict[str, Any]:
        """异步处理图片元素"""
        # 模拟图片处理（如压缩、滤镜等）
        await asyncio.sleep(0.2)
        
        # 模拟图片分析
        image_analysis = await self._analyze_image(element)
        
        return {
            'type': 'image',
            'filename': element.filename,
            'processing_status': 'completed',
            'image_analysis': image_analysis,
            'processed_at': datetime.now().isoformat()
        }
    
    async def visit_videoelement(self, element: VideoElement) -> Dict[str, Any]:
        """异步处理视频元素"""
        # 模拟视频处理（如转码、压缩等）
        await asyncio.sleep(0.3)
        
        # 模拟视频分析
        video_analysis = await self._analyze_video(element)
        
        return {
            'type': 'video',
            'filename': element.filename,
            'processing_status': 'completed',
            'video_analysis': video_analysis,
            'processed_at': datetime.now().isoformat()
        }
    
    async def _analyze_text(self, content: str) -> Dict[str, Any]:
        """异步文本分析"""
        await asyncio.sleep(0.05)  # 模拟分析时间
        
        words = content.split()
        return {
            'word_count': len(words),
            'unique_words': len(set(word.lower() for word in words)),
            'avg_word_length': sum(len(word) for word in words) / max(len(words), 1),
            'complexity_score': min(len(set(word.lower() for word in words)) / max(len(words), 1), 1.0)
        }
    
    async def _analyze_image(self, element: ImageElement) -> Dict[str, Any]:
        """异步图片分析"""
        await asyncio.sleep(0.1)  # 模拟分析时间
        
        return {
            'aspect_ratio': element.width / element.height,
            'pixel_density': element.size / (element.width * element.height),
            'estimated_quality': 'high' if element.size > 1000000 else 'medium' if element.size > 100000 else 'low',
            'format_efficiency': 0.8 if element.format_type.lower() in ['jpg', 'jpeg'] else 0.9 if element.format_type.lower() == 'png' else 0.7
        }
    
    async def _analyze_video(self, element: VideoElement) -> Dict[str, Any]:
        """异步视频分析"""
        await asyncio.sleep(0.15)  # 模拟分析时间
        
        return {
            'duration_category': 'short' if element.duration < 300 else 'medium' if element.duration < 1800 else 'long',
            'quality_score': 0.9 if '4K' in element.resolution else 0.7 if '1080p' in element.resolution else 0.5,
            'compression_efficiency': 0.8 if 'h264' in element.codec.lower() else 0.9 if 'h265' in element.codec.lower() else 0.6,
            'streaming_suitability': element.bitrate <= 5000 and element.duration >= 60
        }


# ============= 实际应用示例 =============

class MediaLibrary:
    """
    媒体库 - 实际应用示例
    
    演示访问者模式在媒体管理系统中的应用
    """
    
    def __init__(self):
        self.elements: List[FunctionalElement] = []
        self.metadata_cache: Dict[str, Any] = {}
    
    def add_element(self, element: FunctionalElement):
        """添加媒体元素"""
        self.elements.append(element)
        # 清除相关缓存
        self.metadata_cache.clear()
    
    def remove_element(self, element: FunctionalElement):
        """移除媒体元素"""
        if element in self.elements:
            self.elements.remove(element)
            self.metadata_cache.clear()
    
    def apply_visitor(self, visitor_func: Callable) -> List[Any]:
        """应用访问者函数"""
        return [element.accept(visitor_func) for element in self.elements]
    
    def apply_registry_visitor(self, visitor_name: str) -> List[Any]:
        """应用注册表中的访问者"""
        results = []
        for element in self.elements:
            try:
                result = visitor_registry.visit(visitor_name, element)
                results.append(result)
            except ValueError as e:
                results.append(f"Error: {e}")
        return results
    
    def get_elements_by_type(self, element_type: Type) -> List[FunctionalElement]:
        """按类型获取元素"""
        return [elem for elem in self.elements if isinstance(elem, element_type)]
    
    def get_library_stats(self) -> Dict[str, Any]:
        """获取库统计信息"""
        stats = {
            'total_elements': len(self.elements),
            'documents': len(self.get_elements_by_type(DocumentElement)),
            'images': len(self.get_elements_by_type(ImageElement)),
            'videos': len(self.get_elements_by_type(VideoElement))
        }
        
        # 计算总大小
        size_results = self.apply_visitor(size_calculator_visitor)
        total_size = sum(result.get('size_bytes', 0) for result in size_results)
        stats['total_size_mb'] = total_size / (1024 * 1024)
        
        return stats
    
    async def process_library_async(self, visitor: AsyncVisitor) -> List[Any]:
        """异步处理整个库"""
        return await visitor.visit_multiple(self.elements)


class ContentAnalyzer:
    """
    内容分析器 - 综合分析工具
    
    使用多种访问者进行内容分析
    """
    
    def __init__(self):
        self.analysis_results: Dict[str, List[Any]] = {}
    
    def analyze_content(self, elements: List[FunctionalElement]) -> Dict[str, Any]:
        """综合内容分析"""
        # 应用多种分析访问者
        self.analysis_results['size_analysis'] = [size_calculator_visitor(elem) for elem in elements]
        self.analysis_results['metadata'] = [metadata_extractor_visitor(elem) for elem in elements]
        
        # 使用注册表访问者
        validation_results = []
        analysis_results = []
        
        for element in elements:
            try:
                validation_results.append(visitor_registry.visit('validator', element))
                analysis_results.append(visitor_registry.visit('analyzer', element))
            except ValueError:
                validation_results.append({'valid': False, 'issues': ['Unsupported element type']})
                analysis_results.append({'error': 'Analysis not supported'})
        
        self.analysis_results['validation'] = validation_results
        self.analysis_results['analysis'] = analysis_results
        
        return self._generate_summary()
    
    def _generate_summary(self) -> Dict[str, Any]:
        """生成分析摘要"""
        # 统计验证结果
        valid_count = sum(1 for result in self.analysis_results['validation'] if result.get('valid', False))
        total_count = len(self.analysis_results['validation'])
        
        # 统计大小信息
        total_size = sum(result.get('size_bytes', 0) for result in self.analysis_results['size_analysis'])
        
        # 统计元素类型
        type_counts = defaultdict(int)
        for result in self.analysis_results['metadata']:
            type_counts[result.get('element_type', 'unknown')] += 1
        
        return {
            'summary': {
                'total_elements': total_count,
                'valid_elements': valid_count,
                'validation_rate': valid_count / max(total_count, 1),
                'total_size_mb': total_size / (1024 * 1024),
                'type_distribution': dict(type_counts)
            },
            'detailed_results': self.analysis_results
        }


# ============= 演示函数 =============

def demonstrate_traditional_visitor():
    """
    演示传统访问者模式
    
    概述引导：
    展示经典的访问者模式实现，包括Element、Visitor接口和具体实现类。
    
    学习要点：
    1. 访问者接口设计
    2. 元素接口设计
    3. 双分派机制
    4. 对象结构管理
    
    关键理解：
    传统访问者模式通过双分派实现操作与数据结构的分离。
    """
    print("=== 传统访问者模式演示 ===")
    print("\n学习目标：")
    print("- 理解访问者模式的结构")
    print("- 掌握双分派机制")
    print("- 学习操作与数据分离")
    print("\n重点概念：")
    print("- 访问者接口")
    print("- 元素接口")
    print("- 对象结构")
    print("=" * 50)
    
    # 创建对象结构
    structure = ObjectStructure()
    
    # 添加元素
    structure.add_element(ConcreteElementA("Hello World"))
    structure.add_element(ConcreteElementB(42))
    structure.add_element(ConcreteElementA("Python Programming"))
    structure.add_element(ConcreteElementB(100))
    
    print(f"\n对象结构包含 {structure.get_element_count()} 个元素")
    
    # 使用打印访问者
    print("\n=== 使用打印访问者 ===")
    print_visitor = ConcreteVisitor1()
    structure.accept(print_visitor)
    
    print(f"\n打印访问者结果数量: {len(print_visitor.get_results())}")
    
    # 使用统计访问者
    print("\n=== 使用统计访问者 ===")
    stats_visitor = ConcreteVisitor2()
    structure.accept(stats_visitor)
    
    stats = stats_visitor.get_statistics()
    print(f"\n统计结果:")
    print(f"  元素计数: {stats['element_count']}")
    print(f"  总值: {stats['total_value']}")
    print(f"  总元素数: {stats['total_elements']}")
    
    # 按类型获取元素
    print("\n=== 按类型统计 ===")
    element_a_count = len(structure.get_elements_by_type(ConcreteElementA))
    element_b_count = len(structure.get_elements_by_type(ConcreteElementB))
    print(f"ElementA 数量: {element_a_count}")
    print(f"ElementB 数量: {element_b_count}")


def demonstrate_functional_visitor():
    """
    演示函数式访问者
    """
    print("\n=== 函数式访问者演示 ===")
    
    # 创建测试元素
    elements = [
        DocumentElement("Python设计模式", "这是一本关于Python设计模式的书籍，详细介绍了各种设计模式在Python中的实现。", "张三"),
        ImageElement("sunset.jpg", 1920, 1080, "jpg"),
        VideoElement("tutorial.mp4", 300.5, "1080p", "h264"),
        DocumentElement("Java vs Python", "比较Java和Python在设计模式实现上的差异。", "李四"),
        ImageElement("diagram.png", 800, 600, "png")
    ]
    
    print(f"\n创建了 {len(elements)} 个测试元素")
    
    # 使用打印访问者
    print("\n=== 打印访问者结果 ===")
    for element in elements:
        element.accept(print_visitor)
    
    # 使用大小计算访问者
    print("\n=== 大小计算访问者结果 ===")
    size_results = [element.accept(size_calculator_visitor) for element in elements]
    
    total_size = 0
    for i, result in enumerate(size_results):
        print(f"  元素{i+1}: {result['type']}, 大小: {result.get('size_mb', result.get('size_kb', result['size_bytes']))} {'MB' if 'size_mb' in result else 'KB' if 'size_kb' in result else 'bytes'}")
        total_size += result['size_bytes']
    
    print(f"\n总大小: {total_size / (1024 * 1024):.2f} MB")
    
    # 使用元数据提取访问者
    print("\n=== 元数据提取访问者结果 ===")
    metadata_results = [element.accept(metadata_extractor_visitor) for element in elements]
    
    for i, metadata in enumerate(metadata_results):
        print(f"  元素{i+1} 元数据:")
        for key, value in metadata.items():
            if key != 'content_preview':  # 跳过长内容预览
                print(f"    {key}: {value}")
        print()


def demonstrate_decorator_visitor():
    """
    演示装饰器访问者
    """
    print("\n=== 装饰器访问者演示 ===")
    
    # 创建测试元素
    elements = [
        DocumentElement("设计模式指南", "这是一个详细的设计模式学习指南，包含了23种经典设计模式的Python实现。每个模式都有详细的解释和示例代码。", "专家作者"),
        ImageElement("architecture.jpg", 2560, 1440, "jpg"),
        VideoElement("course.mp4", 1800, "4K", "h265"),
        DocumentElement("", "短内容", ""),  # 无效文档
        ImageElement("invalid.xyz", -100, 200, "xyz")  # 无效图片
    ]
    
    print(f"\n创建了 {len(elements)} 个测试元素（包含无效元素）")
    
    # 显示已注册的访问者
    registered = visitor_registry.get_registered_visitors()
    print(f"\n已注册的访问者: {list(registered.keys())}")
    
    # 使用格式化访问者
    print("\n=== 格式化访问者结果 ===")
    for i, element in enumerate(elements):
        try:
            result = visitor_registry.visit('formatter', element)
            print(f"元素{i+1}:")
            print(result)
            print()
        except ValueError as e:
            print(f"元素{i+1}: {e}")
    
    # 使用验证访问者
    print("\n=== 验证访问者结果 ===")
    validation_results = []
    for i, element in enumerate(elements):
        try:
            result = visitor_registry.visit('validator', element)
            validation_results.append(result)
            status = "✅ 有效" if result['valid'] else "❌ 无效"
            print(f"元素{i+1} ({result['element_type']}): {status}")
            if not result['valid']:
                for issue in result['issues']:
                    print(f"  - {issue}")
        except ValueError as e:
            print(f"元素{i+1}: 验证失败 - {e}")
            validation_results.append({'valid': False, 'issues': [str(e)]})
    
    # 统计验证结果
    valid_count = sum(1 for result in validation_results if result.get('valid', False))
    print(f"\n验证统计: {valid_count}/{len(validation_results)} 个元素有效")
    
    # 使用分析访问者
    print("\n=== 分析访问者结果 ===")
    for i, element in enumerate(elements):
        try:
            result = visitor_registry.visit('analyzer', element)
            print(f"元素{i+1} 分析结果:")
            for key, value in result.items():
                print(f"  {key}: {value}")
            print()
        except ValueError as e:
            print(f"元素{i+1}: 分析失败 - {e}")


def demonstrate_dynamic_visitor():
    """
    演示动态分发访问者
    """
    print("\n=== 动态分发访问者演示 ===")
    
    # 创建测试元素
    elements = [
        DocumentElement("技术文档", "这是一份技术文档，包含了详细的API说明和使用示例。", "技术团队"),
        ImageElement("screenshot.png", 1366, 768, "png"),
        VideoElement("demo.mp4", 120, "720p", "h264")
    ]
    
    # 使用报告生成访问者
    print("\n=== 报告生成访问者 ===")
    report_visitor = ReportVisitor()
    
    for element in elements:
        result = report_visitor.visit(element)
        print(f"访问结果: {result['type']} - 已记录")
    
    # 生成汇总报告
    summary = report_visitor.generate_summary_report()
    print(f"\n汇总报告:")
    print(f"  总元素数: {summary['summary']['total_elements']}")
    print(f"  文档数: {summary['summary']['documents']}")
    print(f"  图片数: {summary['summary']['images']}")
    print(f"  视频数: {summary['summary']['videos']}")
    print(f"  总字数: {summary['content_stats']['total_words']}")
    print(f"  总视频时长: {summary['content_stats']['total_video_duration']}秒")
    
    # 获取访问统计
    stats = report_visitor.get_statistics()
    print(f"\n访问统计:")
    print(f"  访问次数: {stats['visit_count']}")
    print(f"  总访问数: {stats['total_visits']}")
    print(f"  唯一类型数: {stats['unique_types']}")


async def demonstrate_async_visitor():
    """
    演示异步访问者
    """
    print("\n=== 异步访问者演示 ===")
    
    # 创建测试元素
    elements = [
        DocumentElement("异步处理指南", "这是一份关于异步编程的详细指南，涵盖了asyncio、协程、并发等主题。", "异步专家"),
        ImageElement("async_diagram.jpg", 1920, 1080, "jpg"),
        VideoElement("async_tutorial.mp4", 600, "1080p", "h264"),
        DocumentElement("性能优化", "介绍如何通过异步编程提升应用性能。", "性能专家")
    ]
    
    # 使用异步处理访问者
    async_visitor = AsyncProcessingVisitor()
    
    print(f"\n开始异步处理 {len(elements)} 个元素...")
    start_time = time.time()
    
    # 并发处理所有元素
    results = await async_visitor.visit_multiple(elements)
    
    end_time = time.time()
    
    print(f"\n异步处理完成，耗时: {end_time - start_time:.2f}秒")
    
    # 显示处理结果
    for i, result in enumerate(results):
        print(f"\n元素{i+1} 处理结果:")
        print(f"  类型: {result['type']}")
        print(f"  状态: {result['processing_status']}")
        print(f"  处理时间: {result['processed_at']}")
        
        # 显示分析结果
        if result['type'] == 'document':
            analysis = result['word_analysis']
            print(f"  文本分析: 字数={analysis['word_count']}, 复杂度={analysis['complexity_score']:.2f}")
        elif result['type'] == 'image':
            analysis = result['image_analysis']
            print(f"  图片分析: 质量={analysis['estimated_quality']}, 宽高比={analysis['aspect_ratio']:.2f}")
        elif result['type'] == 'video':
            analysis = result['video_analysis']
            print(f"  视频分析: 类别={analysis['duration_category']}, 质量分数={analysis['quality_score']}")
    
    # 显示性能统计
    perf_stats = async_visitor.get_performance_stats()
    print(f"\n性能统计:")
    print(f"  总处理时间: {perf_stats['total_processing_time']:.2f}秒")
    print(f"  处理元素数: {perf_stats['elements_processed']}")
    print(f"  平均处理时间: {perf_stats['avg_processing_time']:.2f}秒")


def demonstrate_practical_applications():
    """
    演示实际应用
    """
    print("\n=== 实际应用演示 ===")
    
    # 创建媒体库
    library = MediaLibrary()
    
    # 添加各种媒体元素
    library.add_element(DocumentElement("用户手册", "这是产品的详细用户手册，包含了所有功能的使用说明。", "产品团队"))
    library.add_element(DocumentElement("API文档", "RESTful API的完整文档，包含所有端点的详细说明。", "开发团队"))
    library.add_element(ImageElement("logo.png", 512, 512, "png"))
    library.add_element(ImageElement("banner.jpg", 1920, 480, "jpg"))
    library.add_element(VideoElement("intro.mp4", 180, "1080p", "h264"))
    library.add_element(VideoElement("tutorial.mp4", 900, "720p", "h264"))
    
    print(f"\n媒体库包含 {len(library.elements)} 个元素")
    
    # 获取库统计信息
    stats = library.get_library_stats()
    print(f"\n库统计信息:")
    print(f"  总元素数: {stats['total_elements']}")
    print(f"  文档数: {stats['documents']}")
    print(f"  图片数: {stats['images']}")
    print(f"  视频数: {stats['videos']}")
    print(f"  总大小: {stats['total_size_mb']:.2f} MB")
    
    # 使用函数式访问者
    print("\n=== 应用函数式访问者 ===")
    print_results = library.apply_visitor(print_visitor)
    
    # 使用注册表访问者
    print("\n=== 应用格式化访问者 ===")
    format_results = library.apply_registry_visitor('formatter')
    for result in format_results:
        if not isinstance(result, str) or not result.startswith('Error'):
            print(result)
            print()
    
    # 内容分析器演示
    print("\n=== 内容分析器演示 ===")
    analyzer = ContentAnalyzer()
    analysis_result = analyzer.analyze_content(library.elements)
    
    print(f"分析摘要:")
    summary = analysis_result['summary']
    print(f"  总元素数: {summary['total_elements']}")
    print(f"  有效元素数: {summary['valid_elements']}")
    print(f"  验证通过率: {summary['validation_rate']:.1%}")
    print(f"  总大小: {summary['total_size_mb']:.2f} MB")
    print(f"  类型分布: {summary['type_distribution']}")


async def demonstrate_async_practical_application():
    """
    演示异步实际应用
    """
    print("\n=== 异步实际应用演示 ===")
    
    # 创建大型媒体库
    library = MediaLibrary()
    
    # 添加更多元素进行性能测试
    for i in range(5):
        library.add_element(DocumentElement(f"文档{i+1}", f"这是第{i+1}个测试文档，包含大量内容用于性能测试。" * 10, f"作者{i+1}"))
        library.add_element(ImageElement(f"image{i+1}.jpg", 1920 + i*100, 1080 + i*50, "jpg"))
        library.add_element(VideoElement(f"video{i+1}.mp4", 300 + i*60, "1080p", "h264"))
    
    print(f"\n创建了包含 {len(library.elements)} 个元素的大型媒体库")
    
    # 异步处理整个库
    async_visitor = AsyncProcessingVisitor()
    
    print("\n开始异步处理整个媒体库...")
    start_time = time.time()
    
    results = await library.process_library_async(async_visitor)
    
    end_time = time.time()
    
    print(f"异步处理完成，总耗时: {end_time - start_time:.2f}秒")
    print(f"处理了 {len(results)} 个元素")
    
    # 统计处理结果
    success_count = sum(1 for result in results if result.get('processing_status') == 'completed')
    print(f"成功处理: {success_count}/{len(results)} 个元素")
    
    # 显示性能统计
    perf_stats = async_visitor.get_performance_stats()
    print(f"\n性能统计:")
    print(f"  总处理时间: {perf_stats['total_processing_time']:.2f}秒")
    print(f"  平均处理时间: {perf_stats['avg_processing_time']:.3f}秒/元素")
    print(f"  并发效率: {(perf_stats['total_processing_time'] / (end_time - start_time)):.1f}x")


def demonstrate_performance_comparison():
    """
    演示性能对比
    """
    print("\n=== 性能对比演示 ===")
    
    # 创建大量测试数据
    elements = []
    for i in range(1000):
        if i % 3 == 0:
            elements.append(DocumentElement(f"Doc{i}", f"Content {i}" * 20, f"Author{i}"))
        elif i % 3 == 1:
            elements.append(ImageElement(f"img{i}.jpg", 800 + i, 600 + i, "jpg"))
        else:
            elements.append(VideoElement(f"vid{i}.mp4", 60 + i, "720p", "h264"))
    
    print(f"\n创建了 {len(elements)} 个测试元素")
    
    # 传统访问者性能测试
    print("\n=== 传统访问者性能测试 ===")
    start_time = time.time()
    
    # 模拟传统访问者处理
    traditional_results = []
    for element in elements:
        if isinstance(element, DocumentElement):
            result = f"处理文档: {element.title}"
        elif isinstance(element, ImageElement):
            result = f"处理图片: {element.filename}"
        elif isinstance(element, VideoElement):
            result = f"处理视频: {element.filename}"
        traditional_results.append(result)
    
    traditional_time = time.time() - start_time
    print(f"传统方式处理时间: {traditional_time:.3f}秒")
    
    # 函数式访问者性能测试
    print("\n=== 函数式访问者性能测试 ===")
    start_time = time.time()
    
    functional_results = [element.accept(print_visitor) for element in elements]
    
    functional_time = time.time() - start_time
    print(f"函数式方式处理时间: {functional_time:.3f}秒")
    
    # 注册表访问者性能测试
    print("\n=== 注册表访问者性能测试 ===")
    start_time = time.time()
    
    registry_results = []
    for element in elements:
        try:
            result = visitor_registry.visit('formatter', element)
            registry_results.append(result)
        except ValueError:
            registry_results.append("Error")
    
    registry_time = time.time() - start_time
    print(f"注册表方式处理时间: {registry_time:.3f}秒")
    
    # 性能对比总结
    print(f"\n=== 性能对比总结 ===")
    print(f"传统方式: {traditional_time:.3f}秒 (基准)")
    print(f"函数式方式: {functional_time:.3f}秒 ({functional_time/traditional_time:.2f}x)")
    print(f"注册表方式: {registry_time:.3f}秒 ({registry_time/traditional_time:.2f}x)")
    
    fastest = min(traditional_time, functional_time, registry_time)
    if fastest == traditional_time:
        print("最快: 传统方式")
    elif fastest == functional_time:
        print("最快: 函数式方式")
    else:
        print("最快: 注册表方式")


def demonstrate_java_comparison():
    """
    演示与Java的对比
    """
    print("\n=== Python vs Java 访问者模式对比 ===")
    
    print("\n=== Java实现特点 ===")
    print("""
    Java访问者模式的实现:
    
    // Java Visitor接口
    public interface Visitor {
        void visitConcreteElementA(ConcreteElementA element);
        void visitConcreteElementB(ConcreteElementB element);
    }
    
    // Java Element接口
    public interface Element {
        void accept(Visitor visitor);
    }
    
    // 具体元素实现
    public class ConcreteElementA implements Element {
        public void accept(Visitor visitor) {
            visitor.visitConcreteElementA(this);
        }
    }
    
    // 具体访问者实现
    public class ConcreteVisitor implements Visitor {
        public void visitConcreteElementA(ConcreteElementA element) {
            // 处理元素A的逻辑
        }
        
        public void visitConcreteElementB(ConcreteElementB element) {
            // 处理元素B的逻辑
        }
    }
    
    Java特点:
    - 严格的类型检查
    - 编译时方法绑定
    - 需要为每种元素类型定义访问方法
    - 添加新元素类型需要修改访问者接口
    """)
    
    print("\n=== Python实现优势 ===")
    print("""
    Python访问者模式的优势:
    
    1. 动态分发:
       - 运行时方法解析
       - 无需预定义所有访问方法
       - 支持动态添加新的元素类型
    
    2. 函数式支持:
       - 可以使用函数作为访问者
       - 支持lambda表达式
       - 更简洁的实现方式
    
    3. 装饰器模式:
       - 使用装饰器注册访问者
       - 更灵活的访问者管理
       - 支持条件访问者
    
    4. 异步支持:
       - 原生异步访问者支持
       - 并发处理能力
       - 适合I/O密集型操作
    
    5. 反射能力:
       - 运行时类型检查
       - 动态方法调用
       - 更灵活的扩展性
    """)
    
    print("\n=== 使用场景对比 ===")
    print("""
    Java适用场景:
    - 大型企业应用
    - 需要严格类型安全
    - 编译时错误检查
    - 性能关键的应用
    
    Python适用场景:
    - 数据处理和分析
    - 快速原型开发
    - 动态内容处理
    - 异步处理场景
    - 需要运行时扩展的应用
    """)


def main():
    """
    主函数 - 演示所有访问者模式实现
    """
    print("Python访问者模式完整演示")
    print("=" * 60)
    
    # 传统访问者演示
    demonstrate_traditional_visitor()
    
    # 函数式访问者演示
    demonstrate_functional_visitor()
    
    # 装饰器访问者演示
    demonstrate_decorator_visitor()
    
    # 动态分发访问者演示
    demonstrate_dynamic_visitor()
    
    # 异步访问者演示
    print("\n开始异步演示...")
    asyncio.run(demonstrate_async_visitor())
    
    # 实际应用演示
    demonstrate_practical_applications()
    
    # 异步实际应用演示
    print("\n开始异步实际应用演示...")
    asyncio.run(demonstrate_async_practical_application())
    
    # 性能对比演示
    demonstrate_performance_comparison()
    
    # Java对比演示
    demonstrate_java_comparison()
    
    print("\n=== 总结 ===")
    print("""
    访问者模式的Python实现要点:
    
    1. 传统实现：严格遵循GoF模式，适合稳定的类型层次
    2. 函数式实现：使用函数作为访问者，更简洁灵活
    3. 装饰器实现：使用注册表管理访问者，支持动态扩展
    4. 动态分发：利用Python反射能力，自动方法分发
    5. 异步实现：支持异步操作，适合I/O密集型场景
    
    选择建议:
    - 稳定类型层次：使用传统实现
    - 简单操作：使用函数式实现
    - 动态扩展：使用装饰器实现
    - 复杂逻辑：使用动态分发实现
    - 异步场景：使用异步实现
    """)


if __name__ == "__main__":
    main()